package com.koo.modules.api.controller;

import com.alibaba.fastjson.JSON;
import com.koo.common.exception.RRException;
import com.koo.common.utils.MyDateUtil;
import com.koo.common.utils.MyStrUtil;
import com.koo.common.utils.SignUtil;
import com.koo.framework.anno.ApiMethod;
import com.koo.modules.api.service.DownloadApiService;
import com.koo.modules.quartz.constant.B2BTimeConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Controller
@RequestMapping("/api/third")
public class ApiController {
    
    private String dateFormat = B2BTimeConstant.DEFAULT_TIME_FORMAT.getFormat();
    private String apisecret = "84bfccc98bfd498d816138c1917d3529";

    @Autowired
    private DownloadApiService downloadApiService;
    
    @RequestMapping("/test.action")
    @ResponseBody
    public String test(){
        Map<String, Object> paramMap = new ConcurrentHashMap<>();
        paramMap.put("storeId", "f8752237049211e8");
        paramMap.put("startDate", "2019-04-19 13:39:42");
        Map<String, Object> result = downloadApiService.downloadOutOrderData(paramMap);
        return JSON.toJSONStringWithDateFormat(result, dateFormat);
    }
    
    @RequestMapping("/gateway.action")
    @ResponseBody
    public String gateway(@RequestBody Map<String, Object> jsonMap){
        Object returnValue="";
        try{
            if(jsonMap==null
                    || MyStrUtil.isEmpty(jsonMap.get("apikey"))
                    || MyStrUtil.isEmpty(jsonMap.get("method"))
                    || MyStrUtil.isEmpty(jsonMap.get("version"))
                    || MyStrUtil.isEmpty(jsonMap.get("sign"))
                    || MyStrUtil.isEmpty("timestamp")){
                throw new RRException("系统公共参数有误");
            }

            try {
                if(!MyStrUtil.toStr(jsonMap.get("sign")).equals(SignUtil.generateSignature(jsonMap, apisecret))){
                    throw new RRException("校验签名失败");
                }
            } catch (Exception e) {
                throw new RRException("签名异常");
            }
            if(Math.abs(MyDateUtil.dateDiff(MyDateUtil.getCurrDateTime(), MyDateUtil.parseDateByAuto(MyStrUtil.toStr(jsonMap.get("timestamp"))), 12))>30){
                throw new RRException("参数请求超过时效");
            }
            //函数路由
            String method =MyStrUtil.toStr(jsonMap.get("method"));
            if(method.startsWith("api.third.data")){
                returnValue = this.execMethod(downloadApiService, method, jsonMap);
            }
        }catch (Exception e){
            log.error("接口错误",e);
            return this.responseBody(returnValue,500,e.getMessage());
        }
        return this.responseBody(returnValue,200,"成功");
    }
    
    public Object execMethod(Object serviceObj, String methodName, Map<String, Object> jsonMap) {
        Class<?>[] ifclasss = serviceObj.getClass().getInterfaces();
        for (Class<?> ifclass : ifclasss) {
            Method[] methods = ifclass.getDeclaredMethods(); 
            for (Method method : methods) {
                ApiMethod apiMethod = method.getAnnotation(ApiMethod.class);
                if(apiMethod!=null){    
                    if(methodName.equals(apiMethod.value())){
                        try {
                            return method.invoke(serviceObj, jsonMap);
                        } catch (Exception e) {
                            e.printStackTrace();
                            throw new RRException("接口"+methodName+"调用失败");
                        }
                    }
                }
            }
        }
        return null;
    }
    
  

    public String responseBody(Object obj,int statusCode, String msg) {
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("responseBody", obj);
        returnMap.put("code", statusCode);
        returnMap.put("msg", msg);
        return JSON.toJSONStringWithDateFormat(returnMap, dateFormat);
    }

}
